import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_websocket/flutter_websocket.dart';
import 'package:oktoast/oktoast.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return OKToast(
      child: MaterialApp(
        home: _Home(),
      ),
    );
  }
}

class _Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Plugin example app'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () => Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const WebSocketPage()),
          ),
          child: const Text('Go Websocket'),
        ),
      ),
    );
  }
}

class WebSocketPage extends StatefulWidget {
  const WebSocketPage({super.key});

  @override
  State<StatefulWidget> createState() => _WebSocketPageState();
}

class _WebSocketPageState extends State<WebSocketPage> {
  final _ws = FlutterWebsocket();
  final List<String> _received = [];
  List<StreamSubscription>? _subscriptions;

  final _editingController = TextEditingController();
  final _focusNode = FocusNode();

  @override
  void initState() {
    _subscriptions = [
      _ws.stream.listen(
        (event) {
          setState(() {
            _received.add(utf8.decode(event));
          });
        },
        onError: _handleError,
      ),
      _ws.state.listen((event) {
        debugPrint('>> state: $event');
      }),
    ];
    _ws.connect(Uri.parse('wss://echo.websocket.events')).then((_) {
      _ws.sendText('Flutter');
    });
    super.initState();
  }

  @override
  void dispose() {
    _focusNode.unfocus();
    _subscriptions?.forEach((s) => s.cancel());
    _ws.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('WebSocketPage'),
      ),
      body: SafeArea(
          child: Column(
        children: [
          Expanded(
            child: ListView.builder(
              itemBuilder: (context, index) => ListTile(
                title: Text(_received[index]),
              ),
              itemCount: _received.length,
            ),
          ),
          const Divider(),
          _input,
        ],
      )),
    );
  }

  Widget get _input => Row(
        children: [
          Expanded(
            child: Padding(
              padding: const EdgeInsets.symmetric(vertical: 4.0),
              child: TextField(
                controller: _editingController,
                focusNode: _focusNode,
                decoration: const InputDecoration(
                  border: UnderlineInputBorder(),
                ),
              ),
            ),
          ),
          IconButton(
            onPressed: () {
              if (_editingController.text.isEmpty) return;
              _ws.sendText(_editingController.text).catchError(_handleError);
              _editingController.text = '';
              _focusNode.unfocus();
            },
            icon: const Icon(Icons.send),
          ),
        ],
      );

  _handleError(dynamic error) {
    showToast(error.toString());
    debugPrint(error);
  }
}
